import com.google.gdata.client.Query;
import com.google.gdata.client.batch.BatchInterruptedException;
import com.google.gdata.client.calendar.CalendarService;
import com.google.gdata.data.Link;
import com.google.gdata.data.PlainTextConstruct;
import com.google.gdata.data.batch.BatchOperationType;
import com.google.gdata.data.batch.BatchUtils;
import com.google.gdata.data.calendar.CalendarEventEntry;
import com.google.gdata.data.calendar.CalendarEventFeed;
import com.google.gdata.data.extensions.Recurrence;
import com.google.gdata.util.AuthenticationException;
import com.google.gdata.util.ServiceException;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;

/**
 * Performs all tasks related to the calendar and the GCAL service
 * @author Sean Reece
 */
public class Calendar {
	private String username;
	private CalendarService myService;
	private int loginStatus = 0;
	private ArrayList<CalendarEventEntry> eventList = new ArrayList<CalendarEventEntry>();
	SimpleDateFormat formatDate =
		new SimpleDateFormat("yyyyMMdd");
	SimpleDateFormat formatTime =
		new SimpleDateFormat("kkmmss");
	
	/**
	 * Default Constructor. Creates <code>CalendarService(String)</code>
	 */
	public Calendar(){		
		// Create a new Calendar service
		myService = new CalendarService("Algonquin Timetable Parser");
	}

	/**
	 * Uses the user's credentials to authenticate to the Google service. 
	 * @param username
	 * @param password 
	 * @return True on success, false otherwise
	 */
	public boolean login(String username, String password){
		this.username = fixUsername(username);
		// Try to authenticate user credentials
		try {
			myService.setUserCredentials(this.username, password);
			loginStatus = 1;
		} catch (AuthenticationException e) {
			loginStatus = -1;
			return false;
		}
		//(Kind of) Erase Password String
		password = null;
		//Success!
		return true;
	}
	
	/**
	 * Creates a single recurring event and sends it to the google service. The event is now in the user's calendar.
	 */
	public void createRecurringEvent(){
			
		/*try {*/
			/*URL postUrl =
				new URL("http://www.google.com/calendar/feeds/"+ username +"/private/full");*/
			CalendarEventEntry myEntry = new CalendarEventEntry();

			myEntry.setTitle(new PlainTextConstruct(Timetable.getCourseName()+" - "+Timetable.getDelivery()));
			myEntry.setContent(new PlainTextConstruct(Timetable.getCourse()+" with "+Timetable.getProfessor()));
			String recurData = "DTSTART;TZID=America/New_York:"+formatDate.format(Timetable.getStartDate())+"T"+formatTime.format(Timetable.getStartDate())+"\r\n"
			+ "DTEND;TZID=America/New_York:"+formatDate.format(Timetable.getEndDate())+"T"+formatTime.format(Timetable.getEndDate())+"\r\n"
			+ "RRULE:FREQ=WEEKLY;BYDAY="+Timetable.getDayShort()+";UNTIL="+formatDate.format(Timetable.getUntilDate())+"T240000Z\r\n";

			Recurrence recur = new Recurrence();
			recur.setValue(recurData);
			myEntry.setRecurrence(recur);
			myEntry.addLocation(Timetable.getLocation());

			// Send the request and receive the response:
			//CalendarEventEntry insertedEntry = myService.insert(postUrl, myEntry);
			
			eventList.add(myEntry);
		/*}*/
		/*catch(AuthenticationException e) {
			e.printStackTrace();
		}*/
		/*catch(MalformedURLException e) {
			e.printStackTrace();
		}*/
		/*catch(ServiceException e) {
			e.printStackTrace();
		}*/
		/*catch(IOException e) {
			e.printStackTrace();
		}*/
	}
	
	public void insertBatch(){
		URL defaultEventFeedUrl;
		try {
			defaultEventFeedUrl = new URL("https://www.google.com/calendar/feeds/default/private/full");
			CalendarEventFeed feed = myService.getFeed(defaultEventFeedUrl, CalendarEventFeed.class);

			CalendarEventFeed batchRequest = new CalendarEventFeed();
			for (int i=0; i<eventList.size(); i++){
				BatchUtils.setBatchId(eventList.get(i), "i");
				BatchUtils.setBatchOperationType(eventList.get(i), BatchOperationType.INSERT);
				batchRequest.getEntries().add(eventList.get(i));
			}

			Link batchLink = feed.getLink(Link.Rel.FEED_BATCH, Link.Type.ATOM);
			/*CalendarEventFeed batchResponse = */
			myService.batch(new URL(batchLink.getHref()), batchRequest);
                        eventList.clear();
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (BatchInterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ServiceException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * Deletes all events in user's GCal that were previously created by this program.
	 */
	public void removeOldEvents() {
            URL feedUrl, deleteUrl;
            myService.setProtocolVersion(CalendarService.Versions.V1);
		for (int i=0;i<eventList.size();i++){
			try {
                            feedUrl = new URL("https://www.google.com/calendar/feeds/default/private/full");
                            Query myQuery = new Query(feedUrl);
                            myQuery.setFullTextQuery(eventList.get(i).getPlainTextContent());
                            CalendarEventFeed myResultsFeed = myService.query(myQuery,CalendarEventFeed.class);
                            if (myResultsFeed.getEntries().size() > 0) {
                              CalendarEventEntry firstMatchEntry = (CalendarEventEntry)myResultsFeed.getEntries().get(0);
                              System.out.println(firstMatchEntry.getTitle().getPlainText());
                            deleteUrl = new URL(firstMatchEntry.getEditLink().getHref());
				myService.delete(deleteUrl);
                            }
			} catch (MalformedURLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (ServiceException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	/**
	 * If the user does not enter "@gmail.com" then it is added. If so then this does nothing.
	 * @param username
	 * @return The correct username
	 */
	private String fixUsername(String username) {
		if (!username.contains("@gmail.com")){
			username = username.concat("@gmail.com");
		}
		return username;
	}

	/**
	 * 
	 * @return The status of login
	 */
	public int getLoginStatus(){
		return loginStatus;
	}
}
